/*
 * Unidata Platform
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 *
 * Commercial License
 * This version of Unidata Platform is licensed commercially and is the appropriate option for the vast majority of use cases.
 *
 * Please see the Unidata Licensing page at: https://unidata-platform.com/license/
 * For clarification or additional options, please contact: info@unidata-platform.com
 * -------
 * Disclaimer:
 * -------
 * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND
 * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
 * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,
 * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND
 * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.
 */
package org.unidata.mdm.rest.v1.data.converter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import org.unidata.mdm.core.type.data.ArrayAttribute;
import org.unidata.mdm.core.type.data.Attribute;
import org.unidata.mdm.core.type.data.CodeAttribute;
import org.unidata.mdm.core.type.data.ComplexAttribute;
import org.unidata.mdm.core.type.data.SimpleAttribute;
import org.unidata.mdm.core.type.data.TypeOfChange;
import org.unidata.mdm.core.type.data.impl.SimpleAttributesDiff;
import org.unidata.mdm.rest.v1.data.ro.attributes.DiffToPreviousAttributeRO;

/**
 * @author Mikhail Mikhailov
 * Diff tables converter.
 */
public class RecordDiffStateConverter {

    /**
     * Constructor.
     */
    private RecordDiffStateConverter() {
        super();
    }

    public static List<DiffToPreviousAttributeRO> to (SimpleAttributesDiff source) {

        if (Objects.isNull(source) || source.isEmpty()) {
            return Collections.emptyList();
        }

        Map<String, Map<TypeOfChange, Attribute>> table = source.asAttributesTable();
        List<DiffToPreviousAttributeRO> target = new ArrayList<>(table.size());
        for (Entry<String, Map<TypeOfChange, Attribute>> entry : table.entrySet()) {

            // Map size is 1 normally
            Entry<TypeOfChange, Attribute> value = entry.getValue().entrySet().iterator().next();
            DiffToPreviousAttributeRO result = new DiffToPreviousAttributeRO();
            result.setAction(value.getKey().name());
            result.setPath(entry.getKey());

            Attribute attr = value.getValue();
            if (attr != null) {
                switch (attr.getAttributeType()) {
                case ARRAY:
                    ArrayAttribute<?> arrayAttr = attr.narrow();
                    result.setOldArrayValue(ArrayAttributeConverter.to(arrayAttr));
                    break;
                case CODE:
                    CodeAttribute<?> codeAttr = attr.narrow();
                    result.setOldCodeValue(CodeAttributeConverter.to(codeAttr));
                    break;
                case COMPLEX:
                    ComplexAttribute complexAttr = attr.narrow();
                    result.setOldComplexValue(ComplexAttributeConverter.to(complexAttr));
                    break;
                case SIMPLE:
                    SimpleAttribute<?> simpleAttr = attr.narrow();
                    result.setOldSimpleValue(SimpleAttributeConverter.to(simpleAttr));
                    break;
                }
            }

            target.add(result);
        }


        return target;
    }
}
